package com.hujie.sqlqueryes.service.sql;

import com.hujie.sqlqueryes.dto.DslResultDTO;
import com.hujie.sqlqueryes.service.impl.QueryExpressionBuilderImpl;
import com.hujie.sqlqueryes.service.util.JsonEscapeUtil;
import com.hujie.sqlqueryes.service.util.SqlExpressionUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;

/**
 * UPDATE语句处理器
 */
@Component
public class UpdateStatementHandler implements SqlStatementHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(UpdateStatementHandler.class);
    
    @Autowired
    private QueryExpressionBuilderImpl queryExpressionBuilder;
    
    @Override
    public boolean supports(Statement statement) {
        return statement instanceof Update;
    }
    
    @Override
    public DslResultDTO handle(Statement statement) {
        try {
            Update updateStatement = (Update) statement;
            String dsl = buildDslFromUpdate(updateStatement);
            logger.info("UPDATE语句转换完成");
            logger.info("生成的DSL: {}", dsl);
            return DslResultDTO.success(dsl);
        } catch (Exception e) {
            logger.error("UPDATE语句转换失败: {}", e.getMessage(), e);
            return DslResultDTO.error("UPDATE语句转换失败: " + e.getMessage());
        }
    }
    
    private String buildDslFromUpdate(Update updateStatement) {
        Table table = updateStatement.getTable();
        String tableName = table.getName();
        
        // 处理包含特殊字符的索引名称（去除方括号）
        if (tableName != null && tableName.startsWith("[") && tableName.endsWith("]")) {
            tableName = tableName.substring(1, tableName.length() - 1);
        }
        
        logger.debug("解析UPDATE语句: table={}", tableName);
        
        // 获取SET子句
        List<UpdateSet> updateSets = updateStatement.getUpdateSets();
        List<Column> columns = updateStatement.getColumns();
        List<Expression> expressions = updateStatement.getExpressions();
        
        logger.debug("解析UPDATE语句: updateSets={}, columns={}, expressions={}", updateSets, columns, expressions);
        
        // 获取WHERE条件
        Expression where = updateStatement.getWhere();
        
        StringBuilder dsl = new StringBuilder();
        dsl.append("{\n");
        dsl.append("  \"operation\": \"update\",\n");
        dsl.append("  \"index\": \"").append(tableName).append("\",\n");
        
        // 处理SET子句
        dsl.append("  \"doc\": {");
        List<String> updateFields = new ArrayList<>();
        
        // 首先尝试使用updateSets（新版本JSqlParser）
        if (updateSets != null && !updateSets.isEmpty()) {
            logger.debug("使用UpdateSets处理SET子句，数量: {}", updateSets.size());
            for (UpdateSet updateSet : updateSets) {
                List<Column> setColumns = updateSet.getColumns();
                List<Expression> setExpressions = (List<Expression>) updateSet.getValues();
                
                logger.debug("处理UpdateSet，列数: {}, 表达式数: {}", setColumns.size(), setExpressions.size());
                
                int size = Math.min(setColumns.size(), setExpressions.size());
                for (int i = 0; i < size; i++) {
                    String columnName = setColumns.get(i).getColumnName();
                    String value = SqlExpressionUtil.getValueFromExpression(setExpressions.get(i));
                    logger.debug("处理列: {} = {}", columnName, value);
                    // 对字符串值进行转义处理
                    if (!SqlExpressionUtil.isNumeric(value)) {
                        updateFields.add("\"" + columnName + "\": \"" + JsonEscapeUtil.escapeJsonString(value) + "\"");
                    } else {
                        updateFields.add("\"" + columnName + "\": " + value);
                    }
                }
            }
        } 
        // 回退到使用columns和expressions（旧版本兼容）
        else if (columns != null && expressions != null) {
            logger.debug("使用Columns和Expressions处理SET子句，列数: {}, 表达式数: {}", columns.size(), expressions.size());
            // 确保我们使用两个列表中较小的那个作为循环上限
            int size = Math.min(columns.size(), expressions.size());
            logger.debug("使用循环大小: {}", size);
            for (int i = 0; i < size; i++) {
                String columnName = columns.get(i).getColumnName();
                String value = SqlExpressionUtil.getValueFromExpression(expressions.get(i));
                logger.debug("处理列: {} = {}", columnName, value);
                // 对字符串值进行转义处理
                if (!SqlExpressionUtil.isNumeric(value)) {
                    updateFields.add("\"" + columnName + "\": \"" + JsonEscapeUtil.escapeJsonString(value) + "\"");
                } else {
                    updateFields.add("\"" + columnName + "\": " + value);
                }
            }
            // 添加额外的日志，查看是否还有未处理的列或表达式
            if (columns.size() > size) {
                logger.warn("存在未处理的列: {}", columns.subList(size, columns.size()));
            }
            if (expressions.size() > size) {
                logger.warn("存在未处理的表达式: {}", expressions.subList(size, expressions.size()));
            }
        } else {
            logger.debug("列或表达式为空，columns: {}, expressions: {}, updateSets: {}", columns, expressions, updateSets);
        }
        
        dsl.append(String.join(", ", updateFields));
        dsl.append("},\n");
        
        // 处理WHERE条件
        if (where != null) {
            dsl.append("  \"query\": ").append(queryExpressionBuilder.buildQueryFromExpression(where)).append("\n");
        } else {
            dsl.append("  \"query\": {\n    \"match_all\": {}\n  }\n");
        }
        
        dsl.append("}");
        String result = dsl.toString();
        logger.debug("最终生成的DSL: {}", result);
        return result;
    }
}